// utils/request.js 专门用来封装 axios
// 按照 3 个步骤对 axios 进行封装

// 1. 导入 axios 包
import axios from 'axios'
import store from '@/store'
import router from '@/router'
// 按需导入 Loading 成员
import { Loading } from 'element-ui'

// 2. 调用 axios.create() 函数，创建 axios 的实例对象
const instance = axios.create({
  // 全局统一配置请求的根路径
  baseURL: 'http://www.liulongbin.top:3008'
})

// 用来存储 loading 实例的变量
let loadingInstance = null

// 为步骤2创建出来的 instance 配置拦截器
// 请求拦截器  instance.interceptors.request.use(fn1, fn2)
instance.interceptors.request.use(function (config) {
  // Do something before request is sent
  // 展示 loading 效果
  loadingInstance = Loading.service({
    // loading 期间，防止页面滚动
    lock: true,
    // loading 期间，提示的文本消息
    text: 'Loading',
    // loadging 期间，展示的小图标
    spinner: 'el-icon-loading',
    // loading 期间，遮罩层的背景颜色
    background: 'rgba(0, 0, 0, 0.7)'
  })

  // 在 return 之前添加 token
  console.log(config)
  // 结论：只有在 .vue 组件中，才可以使用 this.$store 或 mapXXX 辅助函数
  // 技巧：在 .js 模块中，如果想访问 vuex 全局的东西，直接导入 vuex 的 store 即可~~
  // 严谨（意识）
  if (config.url.startsWith('/my')) {
    config.headers.Authorization = store.state.user.token
  }
  console.log(store)
  return config
}, function (error) {
  // 关闭 loading 效果
  loadingInstance.close()
  // Do something with request error
  return Promise.reject(error)
})

// 响应拦截器
instance.interceptors.response.use(function (response) {
  // Any status code that lie within the range of 2xx cause this function to trigger
  // 如果响应的结果，状态码是 2xx 开头的，则只触发第一个成功的回调
  // Do something with response data
  // 关闭 loading 效果
  loadingInstance.close()
  return response
}, function (error) {
  // 关闭 loading 效果
  loadingInstance.close()
  // Any status codes that falls outside the range of 2xx cause this function to trigger
  // 如果响应的结果，状态码不是以 2xx 开头的，则只触发第二个失败的回调
  console.dir(error)
  if (error.response.status === 401) {
    // token 过期或无效
    // 1. 清空 token
    store.commit('user/updateToken', '')
    // 2. 清空 info
    store.commit('user/updateInfo', {})
    // 3. 跳转到登录页面
    router.push('/login')
  }
  // Do something with response error
  return Promise.reject(error)
})

// 3. 向外导出步骤2创建的 axios 实例，供外界使用
export default instance
